#coding=utf-8
#上传到正式七牛服务器
import sys,os
from qiniu import Auth
from qiniu import BucketManager
from qiniu import Zone
from qiniu import set_default
import qiniu
import uuid
import os.path
from datetime import date
from datetime import datetime
from datetime import timedelta

from flask import request, current_app
from werkzeug import FileStorage, secure_filename

def extension(filename):
    return filename.rsplit('.', 1)[-1]


def lowercase_ext(filename):
    if '.' in filename:
        main, ext = filename.rsplit('.', 1)
        return main + '.' + ext.lower()
    else:
        return filename.lower()


def addslash(url):
    if url.endswith('/'):
        return url
    return url + '/'


def file_allowed(storage, allowed):
    """
    判断文件类型是否允许上传
    @return boolean
    """
    basename = lowercase_ext(secure_filename(storage.filename))
    ext = extension(basename)
    return (ext in allowed)


class QiNiuOSS(object):
    """七牛文件存储"""
    def __init__(self, category, filetype='image', save_path='/data/upload/'):
        """初始化函数
        :param category 类型名称，如:avatar, gallery
        :param save_path 保存文件路径
        """
        self.category      = category
        self.save_path     = save_path
        self.target_folder = ''
        self.target        = ''
        self.key_name      = ''
        self.url           = ''
        self.mime_type     = ''
        self.filetype      = filetype

        # 文件类型
        self.IMAGES = ['jpg' , 'jpeg', 'png', 'bmp', 'gif']
        self.VIDEO = ['flv', 'avi', 'wmv',  'asf', 'dat', 'vob', 'mpg', 'mpeg','rm', 'rmvb', 'mp4', '3gp', 'mkv', 'ogg', 'ogv', 'mov']
        self.TEXT = ['txt']
        self.AUDIO = ['wav', 'mp3', 'aac', 'ogg', 'oga', 'flac']
        self.DOCUMENTS = ['rtf', 'odf', 'ods', 'gnumeric', 'abw', 'doc', 'docx', 'xls', 'xlsx', 'pdf']
        self.DATA = ['csv', 'ini', 'json', 'plist', 'xml', 'yaml', 'yml']
        self.SCRIPTS = ['js', 'php', 'pl', 'py', 'rb', 'sh']
        self.ARCHIVES = ['gz', 'bz2', 'zip', 'tar', 'tgz', 'txz', '7z']
        self.EXECUTABLES =['so', 'exe', 'dll']

        # 七牛配置
        self.access_key            = current_app.config['ACCESS_KEY']
        self.secret_key            = current_app.config['SECRET_KEY']
        self.bucket_name           = current_app.config['BUCKET_NAME']
        self.bucket_domain         = ''

        # 设置七牛默认存储空间
        zone0 = Zone('up-z0.qiniu.com', 'upload-z0.qiniu.com')
        set_default(default_zone=zone0)

    def save(self, storage):
        """保存文件
        :param storage werkzeug.FileStorage
        :param allowed 允许上传的文件类型，默认为图片类型
        :return
        """
        self.storage = storage

        if not isinstance(storage, FileStorage):
            raise TypeError("storage must be a werkzeug.FileStorage")

        folder = "%s" % date.today()
        name = "%s" % uuid.uuid4()
        self.basename  = lowercase_ext(secure_filename(storage.filename))
        self.extension = os.path.splitext(self.storage.filename)[1]
        self.mime_type = storage.headers['Content-Type']
        print u'### self.basename:%s'% self.basename
        basename = name + '.' + extension(self.basename)

        #输出扩张名
        print self.extension

        if self.filetype == 'video':
            allowed = self.VIDEO
        elif self.filetype == 'audio':
            allowed = self.AUDIO
        elif self.filetype == 'documents':
            allowed = self.DOCUMENTS
        else:
            allowed = self.IMAGES

        if self.extension.strip('.') not in allowed:
            raise IOError("storage input error")

        # 目标目录不存在，则创建
        target_folder = os.path.join(self.save_path, self.category, folder)
        self.target_folder = target_folder
        print u'### target_folder:%s'% self.target_folder
        if not os.path.exists(target_folder):
            os.makedirs(target_folder)

        target = os.path.join(target_folder, basename)
        self.key_name = os.path.join(self.category, folder, basename)

        headers = request.headers.get('User-Agent')
        if headers and 'Windows' in headers:
            target_folder = os.path.join(self.save_path, self.category) + '/'+ folder
            target = target_folder + '/' + basename
            self.key_name = self.category + '/' + folder + '/' + basename

        print u'### key_name:%s'% self.key_name
        try:
            storage.save(target)
            self.target = target
        except Exception, e:
            raise e

        self.q = Auth(self.access_key, self.secret_key)
        self.bucket = BucketManager(self.q)
        self.token = self.q.upload_token(self.bucket_name, self.key_name)
        return self.target


    def put_to_oss(self):
        """上传图片至七牛oss"""

        # filetype 1.图片 2.视频 3.音频 4.文档
        info , self.extension = '', self.extension.strip('.')
        if self.filetype == 'video':
            extension = self.VIDEO
        elif self.filetype == 'audio':
            extension = self.AUDIO
        elif self.filetype == 'documents':
            extension = self.DOCUMENTS
        else:
            extension = self.IMAGES

        if self.extension in extension:
            ret, info = qiniu.put_file(self.token, self.key_name, self.target, mime_type=self.mime_type, check_crc=True)
            assert ret['key'] == self.key_name
            assert ret['hash'] == qiniu.etag(self.target)

        if info and info.status_code != 200:
            print 'info.status:%s'% info.status_code
            return ''

        self.url = 'http://oymm6r9xv.bkt.clouddn.com/' + self.key_name
        return self.url


    def get_token(self, basename):
        """获取token"""

        folder = "%s" % date.today()
        name = "%s" % uuid.uuid4()
        self.basename = basename
        print u'### basename:%s'% self.basename
        basename = name + '.' + extension(self.basename)

        self.key_name = os.path.join(self.category, folder, basename)

        print u'### key_name:%s'% self.key_name

        self.q = Auth(self.access_key, self.secret_key)
        # self.bucket = BucketManager(self.q)
        self.token = self.q.upload_token(self.bucket_name, self.key_name)

        return self.token
